package com.example.tool.aop;

import com.example.tool.anno.DictFormat;
import com.example.tool.entity.Dict;
import com.example.tool.service.DictService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Aspect
@Component
public class DictAspect {

    @Autowired
    private DictService dictService;

    @Pointcut("@annotation(com.example.tool.anno.DictFormat)")
    public void pointCut() {}

    @Around("execution(* com.example.tool.service..*.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result=joinPoint.proceed();
        if (null!=result){
            if (result instanceof Collection){
                //转换字典-集合
                ((Collection<?>) result).forEach(this::convertDict);
            }else {
                convertDict(result);
                //转换字典-单体
            }
        }
        return result;
    }

    private void convertDict(Object object){
        Class<?> targetClass = object.getClass(); //获取目标属性Class
        for (Field declaredField : targetClass.getDeclaredFields()) { //获取属性
            if (declaredField.isAnnotationPresent(DictFormat.class)){
                declaredField.setAccessible(true); //设置访问
                //获取字典类型
                DictFormat annotation = declaredField.getAnnotation(DictFormat.class); //获取注解
                String dictType = annotation.value();//获取注解值 ->即字典类型值
                boolean isConvert = annotation.isConvert(); //获取注解值,是否转换字典,默认不转化
                if (isConvert){
                    List<Dict> list = dictService.listByType(dictType); //加载字典服务
                    try {
                        Object fieldValue = declaredField.get(object); //获取字段值 ->字典value
                        if (null!=fieldValue){
                            List<Dict> dictList = list.stream().filter(e -> e.getType().equals(dictType)).collect(Collectors.toList()); //过滤出对应类型的字典
                            Map<String,String> dictCodeAndNameMap=new HashMap<>();
                            for (Dict dict : dictList) {
                                dictCodeAndNameMap.put(dict.getCode(),dict.getName());
                            }
                            declaredField.set(object,dictCodeAndNameMap.get(fieldValue.toString())); //设置到属性值
                        }
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }
}
